package article

import (
	"context"
	"errors"
	"gitee.com/DonHz/basic-go/webook/internal/domain"
	"github.com/bwmarrin/snowflake"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"time"
)

type MongoDBDAO struct {
	//client *mongo.Client
	// 代表webook
	database *mongo.Database
	// 代表制作库
	col *mongo.Collection
	// 线上库
	liveCol *mongo.Collection
	// 雪花算法
	node *snowflake.Node
}

func (m MongoDBDAO) GetByAuthor(ctx context.Context, art domain.Article, offset int, limit int) ([]Article, error) {
	panic("implement me")
}

func (m MongoDBDAO) GetById(ctx context.Context, uid int64) (Article, error) {
	panic("implement me")
}

func (m MongoDBDAO) GetPubById(ctx context.Context, id int64) (ReaderArticle, error) {
	panic("implement me")
}

func NewMongoDBDAO(db *mongo.Database, node *snowflake.Node) ArticleDAO{
	return &MongoDBDAO{
		database: db,
		col: db.Collection("articles"),
		liveCol: db.Collection("reader_articles"),
		node: node,
	}
}

func InitCollections(db *mongo.Database) error {
	ctx, cancel:=context.WithTimeout(context.Background(), time.Second*3)
	defer cancel()
	index:= []mongo.IndexModel{
		{
			Keys: bson.D{bson.E{Key: "id", Value: 1}},
			// 设置索引主键
			Options: options.Index().SetUnique(true),
		},
		{
			Keys: bson.D{bson.E{Key: "author_id", Value: 1},
				bson.E{Key: "create_time", Value: 1}},
			// 设置主键
			Options: options.Index(),
		},
	}
	_, err:=db.Collection("articles").Indexes().CreateMany(ctx, index)
	if err!=nil{
		return err
	}
	_, err=db.Collection("reader_articles").Indexes().CreateMany(ctx, index)
	return err
}

func (m MongoDBDAO) Insert(ctx context.Context, article Article) (int64, error) {
	now := time.Now().UnixMilli()
	article.CreateTime = now
	article.UpdateTime = now
	id:=m.node.Generate().Int64()
	article.Id  = id
	_, err:=m.col.InsertOne(ctx, article)
	if err!=nil{
		return 0, err
	}
	return id, nil
}

func (m MongoDBDAO) UpdateByArticleId(ctx context.Context, article Article) error {
	filter:=bson.M{"id": article.Id, "author_id": article.AuthorId}
	update:=bson.D{bson.E{"$set", bson.M{
		"title": article.Title,
		"content": article.Content,
		"update_time": time.Now().UnixMilli(),
		"status":article.Status,
	}}}
	res, err:=m.col.UpdateOne(ctx, filter, update)
	if err!=nil{
		return err
	}
	if res.ModifiedCount == 0 {
		return errors.New("更新失败")
	}
	return nil
}

func (m MongoDBDAO) Sync(ctx context.Context, article Article) (int64, error) {
	var (
		id = article.Id
		err error
	)
	if id>0 {
		err = m.UpdateByArticleId(ctx, article)
	} else {
		id, err = m.Insert(ctx, article)
	}
	if err!=nil{
		return 0, err
	}
	article.Id=id
	// 操作线上库
	now:=time.Now().UnixMilli()
	article.UpdateTime=now
	filter:=bson.M{"id": article.Id}
	_, err=m.liveCol.UpdateOne(ctx, filter, bson.D{
		bson.E{"$set", ReaderArticle{article}},
		bson.E{"$setOnInsert", bson.D{bson.E{"create_time", now}}},
	}, options.Update().SetUpsert(true))
	return id, err
}

func (m MongoDBDAO) Upsert(ctx context.Context, article ReaderArticle) error {
	return nil
}

func (m MongoDBDAO) SyncStatus(ctx context.Context, article Article) error {
	return nil
}



